import 'dart:async';
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:vr/model/trtc_auth_info_data.dart';
import 'package:permission_handler/permission_handler.dart';

typedef void VrCreatedCallback(VrController controller);

class Vr extends StatefulWidget {

  final String initialPath;
  final int hiddenTitle;
  final int fullScreen;
  final int isFromReceive;
  final String shareBaseUrl;
  final int tenantId;
  final int userId;

  static const MethodChannel _channel = const MethodChannel('flutter_plugin');

  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  const Vr({
    Key key,
    this.onVrCreated,
    this.hiddenTitle,
    this.fullScreen,
    this.isFromReceive,
    @required this.shareBaseUrl,
    @required this.tenantId,
    @required this.initialPath,
    @required this.userId,
  }) : assert(initialPath != null);

  final VrCreatedCallback onVrCreated;

  @override
  _VrState createState() => _VrState();
}

class _VrState extends State<Vr> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (defaultTargetPlatform == TargetPlatform.android) {
      return AndroidView(
        viewType: 'plugins.com.asman/vr',
        onPlatformViewCreated: _onPlatformViewCreated,
        layoutDirection: TextDirection.ltr,
        creationParams: <String, dynamic>{
          "urlPath": widget.initialPath,
          "hiddenTitle": widget.hiddenTitle,
          "fullScreen": widget.fullScreen,
          "isFromReceive": widget.isFromReceive,
          "shareBaseUrl": widget.shareBaseUrl,
          "tenantId": widget.tenantId,
        },
        creationParamsCodec: const StandardMessageCodec(),
      );
    }
    if (defaultTargetPlatform == TargetPlatform.iOS) {
      final kScreenHeight = MediaQuery.of(context).size.height;
      return Container(
        height: kScreenHeight,
        child: UiKitView(
          viewType: "plugins.com.asman/vr",
          creationParams: <String, dynamic>{
            "urlPath": widget.initialPath,
            "isFromReceive": widget.isFromReceive,
            "shareBaseUrl":widget.shareBaseUrl,
            "tenantId":widget.tenantId,
            "userId":widget.userId.toString(),
          },
          creationParamsCodec: StandardMessageCodec(),
          onPlatformViewCreated: _onPlatformViewCreated,
        ),
      );
    }
    return Text("目前只提供安卓和 ios 平台支持，其他平台等待实现");
  }

  void _onPlatformViewCreated(int id) {
    if (widget.onVrCreated == null) {
      return;
    }
    VrController controller = new VrController._(id);
    widget.onVrCreated(controller);
  }
}

class VrController {
  VrController._(int id)
      : _channel = new MethodChannel('plugins.com.asman/vr_$id');

  final MethodChannel _channel;

  Function routeToDecorateDetail;
  Function onGoBack;
  Function getTrtcAuthInfo;
  Function notifyDesignerJoined;
  Function switchToDesignerShopView;
  Function generateShareWidget;
  Function checkMini;

  Future<dynamic> _addNativeMethod(MethodCall methodCall) async {
    print(methodCall.method);
    print(methodCall.arguments);
    switch (methodCall.method) {
      case "routeToDecorateDetail":
        var params = methodCall.arguments;

        num schemeId;
        num workId;
        Map<String, dynamic> hotspots;

        if (defaultTargetPlatform == TargetPlatform.android) {
          Map<String, dynamic> decorateDetailParam = json.decode(params);
          schemeId = decorateDetailParam['schemeId'];
          workId = decorateDetailParam['workId'];
          hotspots = decorateDetailParam['hotspots'];
        }
        if (defaultTargetPlatform == TargetPlatform.iOS) {
          Map<String, dynamic> decorateDetailParam = json.decode(params);
          final tempSchemeId = decorateDetailParam["schemeId"];
          if(tempSchemeId is num){
            schemeId = tempSchemeId;
          }else if(tempSchemeId is String){
            schemeId = num.parse(tempSchemeId);
          }
          final tempWorkId = decorateDetailParam["workId"];
          if(tempWorkId is num){
            workId = tempWorkId;
          }else if(tempWorkId is String){
            workId = num.parse(tempWorkId);
          }
          hotspots = decorateDetailParam['hotspots'];
        }
        routeToDecorateDetail(schemeId, workId, hotspots);
        break;

      case "onGoBack":
        String params = methodCall.arguments;
        onGoBack(params);
        break;

      case "getTrtcAuthInfo":
        getTrtcAuthInfo();
        break;

      case "notifyDesignerJoined":
        notifyDesignerJoined();
        break;

      case "requestAudioPermission":
        String callbackName = methodCall.arguments;
        var cbArr = callbackName.split(",");
        requestAudioPermission(cbArr[0], cbArr[1]);
        break;

      case "switchToDesignerShopView":
        int designerId = methodCall.arguments;
        switchToDesignerShopView(designerId);
        break;

      case "checkMini":
        // int designerId = methodCall.arguments;
        try {
          await checkMini();
          return true;
        } catch(e) {
          return false;
        }
        break;

      case "generateShareWidget":
        String img = methodCall.arguments['img'];
        String title = methodCall.arguments['title'];
        String price = methodCall.arguments['price'];
        String shareUrl = methodCall.arguments['shareUrl'];
        print("_generateShareWidget_generateShareWidget");
        generateShareWidget(img, title, price, shareUrl);
        break;
    }
  }

  void addNativeMethod({
    Function routeToDecorateDetail,
    Function onGoBack,
    Function getTrtcAuthInfo,
    Function notifyDesignerJoined,
    Function switchToDesignerShopView,
    Function generateShareWidget,
    Function checkMini,
  }) {
     print("routeToDecorateDetail  --  method did add");
     this.routeToDecorateDetail = routeToDecorateDetail;
     this.onGoBack = onGoBack;
     this.getTrtcAuthInfo = getTrtcAuthInfo;
     this.notifyDesignerJoined = notifyDesignerJoined;
     this.switchToDesignerShopView = switchToDesignerShopView;
     this.generateShareWidget = generateShareWidget;
     this.checkMini = checkMini;

     _channel.setMethodCallHandler(_addNativeMethod);
  }

  // 调用原生 flutter 方法
  Future<void> joinRoom(TrtcAuthInfoData trtcAuthInfoData) async {

    var trtcAuthInfoDataMap = trtcAuthInfoData.toJson();
    var trtcAuthInfoDataJson = json.encode(trtcAuthInfoDataMap);
    _channel.invokeMethod('joinRoom', trtcAuthInfoDataJson);
  }
  Future<void> backPressed() async {
    _channel.invokeMethod('onBackPressed');
  }

  requestAudioPermission(String successCallbackName, String failCallbackName) async {
    var status = await Permission.microphone.status;
    if (status.isUndetermined || status.isDenied) {
      var result = await Permission.microphone.request();
      if (result.isGranted) {
        _channel.invokeMethod(successCallbackName);
      } else {
        _channel.invokeMethod(failCallbackName);
      }
    } else {
      _channel.invokeMethod(successCallbackName);
    }
  }

  trtcExitRoom() {
    _channel.invokeMethod('trtcExitRoom');
  }

  shareToWX(String base64Data) {
    _channel.invokeMethod('shoreToWX', base64Data);
  }

  callShareCallback() {
    _channel.invokeMethod('shareCallback');
  }

  // 调用原生的方法
  /*Future<void> setText(String text) async {
    assert(text != null);
    return _channel.invokeMethod('setText', text);
  }*/

}
